package main

import "fmt"

/*
	   Channel 管道
		 管道是golang在语言级别上提供的goroutine间的通讯方式，我们可以使用channel在多个goroutine之间传递信息。
		 管道（channel）是一种特殊的类型  先入先出
*/
func main() {
	/*
		   1、channel 类型
			 channel是一种类型 引用类型
			 var 变量 chan 元素类型
	*/
	/*
	    var ch1 chan int      //声明一个传递整形的管道
	   	var ch2 chan string   //声明一个传递字符串的管道
	   	var ch3 chan bool     //声明一个传递bool的管道
	   	var ch4 chan []string //声明一个传递字符串切片的管道
	*/

	/*
	   2、创建channel
	*/
	ch := make(chan int, 4)
	/*
	  3、给管道存储数据（将数据放在管道内）
	*/
	ch <- 10
	ch <- 21
	ch <- 33
	ch <- 50
	/*
		   4、从管道内取值（从管道内取值）
			 <- ch 表示取值 不操作该值
	*/
	x := <-ch      //从ch管道取值赋值给x
	fmt.Println(x) //10

	<-ch //取值 不操作
	c := <-ch
	fmt.Println(c) //33

	/*
	  5、管道长度&容量
	*/
	fmt.Printf("长度=%v,值=%v,容量：%v,类型：%T\n", len(ch), ch, cap(ch), ch) //长度=1,值=0x14000104000,容量：4,类型：chan int

	/*
	   6、管道类型（引用数据类型）
	*/
	ch1 := make(chan int, 4)
	ch1 <- 45
	ch1 <- 67
	ch1 <- 89
	ch2 := ch1
	ch2 <- 99
	<-ch1
	<-ch1
	<-ch1
	d := <-ch1
	fmt.Println(d) //99

	/*
	  7、管道阻塞
	*/
	// ch5 := make(chan int, 1)
	// ch5 <- 34
	// ch5 <- 88  // all goroutines are asleep - deadlock!
	ch6 := make(chan string, 2)
	ch6 <- "Hello"
	ch6 <- "World"
	str1 := <-ch6
	str2 := <-ch6
	str3 := <-ch6
	fmt.Println(str1, str2, str3) //all goroutines are asleep - deadlock!
}
